﻿using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using HslCommunication.BasicFramework;
using HslCommunication.Core;
using HslCommunication.Core.Net;
using HslCommunication.Reflection;

namespace HslCommunication.Profinet.Panasonic
{
	/// <summary>
	/// 松下PLC的数据交互协议，采用Mewtocol协议通讯，基于Tcp透传实现的机制，支持的地址列表参考api文档<br />
	/// The data exchange protocol of Panasonic PLC adopts Mewtocol protocol for communication. 
	/// It is based on the mechanism of Tcp transparent transmission. For the list of supported addresses, refer to the api document.
	/// </summary>
	/// <remarks>
	/// 地址支持携带站号的访问方式，例如：s=2;D100
	/// </remarks>
	/// <example>
	/// 触点地址的输入的格式说明如下：
	/// <list type="table">
	///   <listheader>
	///     <term>地址名称</term>
	///     <term>地址代号</term>
	///     <term>示例</term>
	///     <term>地址进制</term>
	///     <term>字操作</term>
	///     <term>位操作</term>
	///     <term>备注</term>
	///   </listheader>
	///   <item>
	///     <term>外部输入继电器</term>
	///     <term>X</term>
	///     <term>X11,X1F</term>
	///     <term>10</term>
	///     <term>×</term>
	///     <term>√</term>
	///     <term>X33 等同于 X3.3</term>
	///   </item>
	///   <item>
	///     <term>外部输出继电器</term>
	///     <term>Y</term>
	///     <term>Y22,Y2A</term>
	///     <term>10</term>
	///     <term>×</term>
	///     <term>√</term>
	///     <term>Y21 等同于 Y2.1</term>
	///   </item>
	///   <item>
	///     <term>内部继电器</term>
	///     <term>R</term>
	///     <term>R0F,R100F</term>
	///     <term>10</term>
	///     <term>×</term>
	///     <term>√</term>
	///     <term>R21 等同于 R2.1</term>
	///   </item>
	///   <item>
	///     <term>定时器</term>
	///     <term>T</term>
	///     <term>T0,T100</term>
	///     <term>10</term>
	///     <term>×</term>
	///     <term>√</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>计数器</term>
	///     <term>C</term>
	///     <term>C0,C100</term>
	///     <term>10</term>
	///     <term>×</term>
	///     <term>√</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>链接继电器</term>
	///     <term>L</term>
	///     <term>L0F,L100F</term>
	///     <term>10</term>
	///     <term>×</term>
	///     <term>√</term>
	///     <term>L21 等同于 L2.1</term>
	///   </item>
	/// </list>
	/// 数据地址的输入的格式说明如下：
	/// <list type="table">
	///   <listheader>
	///     <term>地址名称</term>
	///     <term>地址代号</term>
	///     <term>示例</term>
	///     <term>地址进制</term>
	///     <term>字操作</term>
	///     <term>位操作</term>
	///     <term>备注</term>
	///   </listheader>
	///   <item>
	///     <term>数据寄存器 DT</term>
	///     <term>D</term>
	///     <term>D0,D100</term>
	///     <term>10</term>
	///     <term>√</term>
	///     <term>×</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>链接寄存器 LD</term>
	///     <term>LD</term>
	///     <term>LD0,LD100</term>
	///     <term>10</term>
	///     <term>√</term>
	///     <term>×</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>文件寄存器 FL</term>
	///     <term>F</term>
	///     <term>F0,F100</term>
	///     <term>10</term>
	///     <term>√</term>
	///     <term>×</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>目标值 SV</term>
	///     <term>S</term>
	///     <term>S0,S100</term>
	///     <term>10</term>
	///     <term>√</term>
	///     <term>×</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>经过值 EV</term>
	///     <term>K</term>
	///     <term>K0,K100</term>
	///     <term>10</term>
	///     <term>√</term>
	///     <term>×</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>索引寄存器 IX</term>
	///     <term>IX</term>
	///     <term>IX0,IX100</term>
	///     <term>10</term>
	///     <term>√</term>
	///     <term>×</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>索引寄存器 IY</term>
	///     <term>IY</term>
	///     <term>IY0,IY100</term>
	///     <term>10</term>
	///     <term>√</term>
	///     <term>×</term>
	///     <term></term>
	///   </item>
	/// </list>
	/// </example>
	// Token: 0x02000055 RID: 85
	public class PanasonicMewtocolOverTcp : NetworkDeviceSoloBase
	{
		/// <summary>
		/// 实例化一个默认的松下PLC通信对象，默认站号为0xEE<br />
		/// Instantiate a default Panasonic PLC communication object, the default station number is 0xEE
		/// </summary>
		/// <param name="station">站号信息，默认为0xEE</param>
		// Token: 0x060006E3 RID: 1763 RVA: 0x00024323 File Offset: 0x00022523
		public PanasonicMewtocolOverTcp(byte station = 238)
		{
			base.ByteTransform = new RegularByteTransform();
			this.Station = station;
			base.ByteTransform.DataFormat = DataFormat.DCBA;
		}

		/// <summary>
		/// 实例化一个默认的松下PLC通信对象，指定ip地址，端口，默认站号为0xEE<br />
		/// Instantiate a default Panasonic PLC communication object, specify the IP address, port, and the default station number is 0xEE
		/// </summary>
		/// <param name="ipAddress">Ip地址数据</param>
		/// <param name="port">端口号</param>
		/// <param name="station">站号信息，默认为0xEE</param>
		// Token: 0x060006E4 RID: 1764 RVA: 0x0002434E File Offset: 0x0002254E
		public PanasonicMewtocolOverTcp(string ipAddress, int port, byte station = 238)
		{
			base.ByteTransform = new RegularByteTransform();
			this.Station = station;
			base.ByteTransform.DataFormat = DataFormat.DCBA;
			this.IpAddress = ipAddress;
			this.Port = port;
		}

		/// <summary>
		/// PLC设备的目标站号，需要根据实际的设置来填写<br />
		/// The target station number of the PLC device needs to be filled in according to the actual settings
		/// </summary>
		// Token: 0x1700014C RID: 332
		// (get) Token: 0x060006E5 RID: 1765 RVA: 0x00024389 File Offset: 0x00022589
		// (set) Token: 0x060006E6 RID: 1766 RVA: 0x00024391 File Offset: 0x00022591
		public byte Station { get; set; }

		/// <summary>
		/// 读取指定地址的原始数据，地址示例：D0  F0  K0  T0  C0, 地址支持携带站号的访问方式，例如：s=2;D100<br />
		/// Read the original data of the specified address, address example: D0 F0 K0 T0 C0, the address supports carrying station number information, for example: s=2;D100
		/// </summary>
		/// <param name="address">起始地址</param>
		/// <param name="length">长度</param>
		/// <returns>原始的字节数据的信息</returns>
		// Token: 0x060006E7 RID: 1767 RVA: 0x0002439C File Offset: 0x0002259C
		[HslMqttApi("ReadByteArray", "")]
		public override OperateResult<byte[]> Read(string address, ushort length)
		{
			byte station = (byte)HslHelper.ExtractParameter(ref address, "s", (int)this.Station);
			OperateResult<byte[]> operateResult = PanasonicHelper.BuildReadCommand(station, address, length);
			bool flag = !operateResult.IsSuccess;
			OperateResult<byte[]> result;
			if (flag)
			{
				result = operateResult;
			}
			else
			{
				OperateResult<byte[]> operateResult2 = base.ReadFromCoreServer(operateResult.Content);
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = operateResult2;
				}
				else
				{
					result = PanasonicHelper.ExtraActualData(operateResult2.Content);
				}
			}
			return result;
		}

		/// <summary>
		/// 将数据写入到指定的地址里去，地址示例：D0  F0  K0  T0  C0, 地址支持携带站号的访问方式，例如：s=2;D100<br />
		/// Write data to the specified address, address example: D0 F0 K0 T0 C0, the address supports carrying station number information, for example: s=2;D100
		/// </summary>
		/// <param name="address">起始地址</param>
		/// <param name="value">真实数据</param>
		/// <returns>是否写入成功</returns>
		// Token: 0x060006E8 RID: 1768 RVA: 0x0002440C File Offset: 0x0002260C
		[HslMqttApi("WriteByteArray", "")]
		public override OperateResult Write(string address, byte[] value)
		{
			byte station = (byte)HslHelper.ExtractParameter(ref address, "s", (int)this.Station);
			OperateResult<byte[]> operateResult = PanasonicHelper.BuildWriteCommand(station, address, value);
			bool flag = !operateResult.IsSuccess;
			OperateResult result;
			if (flag)
			{
				result = operateResult;
			}
			else
			{
				OperateResult<byte[]> operateResult2 = base.ReadFromCoreServer(operateResult.Content);
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = operateResult2;
				}
				else
				{
					result = PanasonicHelper.ExtraActualData(operateResult2.Content);
				}
			}
			return result;
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Panasonic.PanasonicMewtocolOverTcp.Read(System.String,System.UInt16)" />
		// Token: 0x060006E9 RID: 1769 RVA: 0x0002447C File Offset: 0x0002267C
		[DebuggerStepThrough]
		public override Task<OperateResult<byte[]>> ReadAsync(string address, ushort length)
		{
			PanasonicMewtocolOverTcp.<ReadAsync>d__8 <ReadAsync>d__ = new PanasonicMewtocolOverTcp.<ReadAsync>d__8();
			<ReadAsync>d__.<>t__builder = AsyncTaskMethodBuilder<OperateResult<byte[]>>.Create();
			<ReadAsync>d__.<>4__this = this;
			<ReadAsync>d__.address = address;
			<ReadAsync>d__.length = length;
			<ReadAsync>d__.<>1__state = -1;
			<ReadAsync>d__.<>t__builder.Start<PanasonicMewtocolOverTcp.<ReadAsync>d__8>(ref <ReadAsync>d__);
			return <ReadAsync>d__.<>t__builder.Task;
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Panasonic.PanasonicMewtocolOverTcp.Write(System.String,System.Byte[])" />
		// Token: 0x060006EA RID: 1770 RVA: 0x000244D0 File Offset: 0x000226D0
		[DebuggerStepThrough]
		public override Task<OperateResult> WriteAsync(string address, byte[] value)
		{
			PanasonicMewtocolOverTcp.<WriteAsync>d__9 <WriteAsync>d__ = new PanasonicMewtocolOverTcp.<WriteAsync>d__9();
			<WriteAsync>d__.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
			<WriteAsync>d__.<>4__this = this;
			<WriteAsync>d__.address = address;
			<WriteAsync>d__.value = value;
			<WriteAsync>d__.<>1__state = -1;
			<WriteAsync>d__.<>t__builder.Start<PanasonicMewtocolOverTcp.<WriteAsync>d__9>(ref <WriteAsync>d__);
			return <WriteAsync>d__.<>t__builder.Task;
		}

		/// <summary>
		/// 批量读取松下PLC的位数据，按照字为单位，地址为 X0,X10,Y10，读取的长度为16的倍数<br />
		/// Read the bit data of Panasonic PLC in batches, the unit is word, the address is X0, X10, Y10, and the read length is a multiple of 16
		/// </summary>
		/// <param name="address">起始地址</param>
		/// <param name="length">数据长度</param>
		/// <returns>读取结果对象</returns>
		// Token: 0x060006EB RID: 1771 RVA: 0x00024524 File Offset: 0x00022724
		[HslMqttApi("ReadBoolArray", "")]
		public override OperateResult<bool[]> ReadBool(string address, ushort length)
		{
			byte station = (byte)HslHelper.ExtractParameter(ref address, "s", (int)this.Station);
			OperateResult<string, int> operateResult = PanasonicHelper.AnalysisAddress(address);
			bool flag = !operateResult.IsSuccess;
			OperateResult<bool[]> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<bool[]>(operateResult);
			}
			else
			{
				OperateResult<byte[]> operateResult2 = PanasonicHelper.BuildReadCommand(station, address, length);
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = OperateResult.CreateFailedResult<bool[]>(operateResult2);
				}
				else
				{
					OperateResult<byte[]> operateResult3 = base.ReadFromCoreServer(operateResult2.Content);
					bool flag3 = !operateResult3.IsSuccess;
					if (flag3)
					{
						result = OperateResult.CreateFailedResult<bool[]>(operateResult3);
					}
					else
					{
						OperateResult<byte[]> operateResult4 = PanasonicHelper.ExtraActualData(operateResult3.Content);
						bool flag4 = !operateResult4.IsSuccess;
						if (flag4)
						{
							result = OperateResult.CreateFailedResult<bool[]>(operateResult4);
						}
						else
						{
							result = OperateResult.CreateSuccessResult<bool[]>(SoftBasic.ByteToBoolArray(operateResult4.Content).SelectMiddle(operateResult.Content2 % 16, (int)length));
						}
					}
				}
			}
			return result;
		}

		/// <summary>
		/// 读取单个的地址信息的bool值，地址举例：SR0.0  X0.0  Y0.0  R0.0  L0.0<br />
		/// Read the bool value of a single address, for example: SR0.0 X0.0 Y0.0 R0.0 L0.0
		/// </summary>
		/// <param name="address">起始地址</param>
		/// <returns>读取结果对象</returns>
		// Token: 0x060006EC RID: 1772 RVA: 0x00024600 File Offset: 0x00022800
		[HslMqttApi("ReadBool", "")]
		public override OperateResult<bool> ReadBool(string address)
		{
			byte station = (byte)HslHelper.ExtractParameter(ref address, "s", (int)this.Station);
			OperateResult<byte[]> operateResult = PanasonicHelper.BuildReadOneCoil(station, address);
			bool flag = !operateResult.IsSuccess;
			OperateResult<bool> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<bool>(operateResult);
			}
			else
			{
				OperateResult<byte[]> operateResult2 = base.ReadFromCoreServer(operateResult.Content);
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = OperateResult.CreateFailedResult<bool>(operateResult2);
				}
				else
				{
					result = PanasonicHelper.ExtraActualBool(operateResult2.Content);
				}
			}
			return result;
		}

		/// <summary>
		/// 往指定的地址写入 <see cref="T:System.Boolean" /> 数组，地址举例：SR0.0  X0.0  Y0.0  R0.0  L0.0，
		/// 起始的位地址必须为16的倍数，写入的 <see cref="T:System.Boolean" /> 数组长度也为16的倍数。<br />
		/// Write the <see cref="T:System.Boolean" /> array to the specified address, address example: SR0.0 X0.0 Y0.0 R0.0 L0.0, 
		/// the starting bit address must be a multiple of 16. <see cref="T:System.Boolean" /> The length of the array is also a multiple of 16. <br />
		/// </summary>
		/// <param name="address">起始地址</param>
		/// <param name="values">数据值信息</param>
		/// <returns>返回是否成功的结果对象</returns>
		// Token: 0x060006ED RID: 1773 RVA: 0x00024678 File Offset: 0x00022878
		[HslMqttApi("WriteBoolArray", "")]
		public override OperateResult Write(string address, bool[] values)
		{
			byte station = (byte)HslHelper.ExtractParameter(ref address, "s", (int)this.Station);
			OperateResult<string, int> operateResult = PanasonicHelper.AnalysisAddress(address);
			bool flag = !operateResult.IsSuccess;
			OperateResult result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<bool[]>(operateResult);
			}
			else
			{
				bool flag2 = operateResult.Content2 % 16 != 0;
				if (flag2)
				{
					result = new OperateResult(StringResources.Language.PanasonicAddressBitStartMulti16);
				}
				else
				{
					bool flag3 = values.Length % 16 != 0;
					if (flag3)
					{
						result = new OperateResult(StringResources.Language.PanasonicBoolLengthMulti16);
					}
					else
					{
						byte[] values2 = SoftBasic.BoolArrayToByte(values);
						OperateResult<byte[]> operateResult2 = PanasonicHelper.BuildWriteCommand(station, address, values2);
						bool flag4 = !operateResult2.IsSuccess;
						if (flag4)
						{
							result = operateResult2;
						}
						else
						{
							OperateResult<byte[]> operateResult3 = base.ReadFromCoreServer(operateResult2.Content);
							bool flag5 = !operateResult3.IsSuccess;
							if (flag5)
							{
								result = operateResult3;
							}
							else
							{
								result = PanasonicHelper.ExtraActualData(operateResult3.Content);
							}
						}
					}
				}
			}
			return result;
		}

		/// <summary>
		/// 往指定的地址写入bool数据，地址举例：SR0.0  X0.0  Y0.0  R0.0  L0.0<br />
		/// Write bool data to the specified address. Example address: SR0.0 X0.0 Y0.0 R0.0 L0.0
		/// </summary>
		/// <param name="address">起始地址</param>
		/// <param name="value">数据值信息</param>
		/// <returns>返回是否成功的结果对象</returns>
		// Token: 0x060006EE RID: 1774 RVA: 0x00024760 File Offset: 0x00022960
		[HslMqttApi("WriteBool", "")]
		public override OperateResult Write(string address, bool value)
		{
			byte station = (byte)HslHelper.ExtractParameter(ref address, "s", (int)this.Station);
			OperateResult<byte[]> operateResult = PanasonicHelper.BuildWriteOneCoil(station, address, value);
			bool flag = !operateResult.IsSuccess;
			OperateResult result;
			if (flag)
			{
				result = operateResult;
			}
			else
			{
				OperateResult<byte[]> operateResult2 = base.ReadFromCoreServer(operateResult.Content);
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = operateResult2;
				}
				else
				{
					result = PanasonicHelper.ExtraActualData(operateResult2.Content);
				}
			}
			return result;
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Panasonic.PanasonicMewtocolOverTcp.ReadBool(System.String)" />
		// Token: 0x060006EF RID: 1775 RVA: 0x000247D0 File Offset: 0x000229D0
		[DebuggerStepThrough]
		public override Task<OperateResult<bool[]>> ReadBoolAsync(string address, ushort length)
		{
			PanasonicMewtocolOverTcp.<ReadBoolAsync>d__14 <ReadBoolAsync>d__ = new PanasonicMewtocolOverTcp.<ReadBoolAsync>d__14();
			<ReadBoolAsync>d__.<>t__builder = AsyncTaskMethodBuilder<OperateResult<bool[]>>.Create();
			<ReadBoolAsync>d__.<>4__this = this;
			<ReadBoolAsync>d__.address = address;
			<ReadBoolAsync>d__.length = length;
			<ReadBoolAsync>d__.<>1__state = -1;
			<ReadBoolAsync>d__.<>t__builder.Start<PanasonicMewtocolOverTcp.<ReadBoolAsync>d__14>(ref <ReadBoolAsync>d__);
			return <ReadBoolAsync>d__.<>t__builder.Task;
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Panasonic.PanasonicMewtocolOverTcp.ReadBool(System.String)" />
		// Token: 0x060006F0 RID: 1776 RVA: 0x00024824 File Offset: 0x00022A24
		[DebuggerStepThrough]
		public override Task<OperateResult<bool>> ReadBoolAsync(string address)
		{
			PanasonicMewtocolOverTcp.<ReadBoolAsync>d__15 <ReadBoolAsync>d__ = new PanasonicMewtocolOverTcp.<ReadBoolAsync>d__15();
			<ReadBoolAsync>d__.<>t__builder = AsyncTaskMethodBuilder<OperateResult<bool>>.Create();
			<ReadBoolAsync>d__.<>4__this = this;
			<ReadBoolAsync>d__.address = address;
			<ReadBoolAsync>d__.<>1__state = -1;
			<ReadBoolAsync>d__.<>t__builder.Start<PanasonicMewtocolOverTcp.<ReadBoolAsync>d__15>(ref <ReadBoolAsync>d__);
			return <ReadBoolAsync>d__.<>t__builder.Task;
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Panasonic.PanasonicMewtocolOverTcp.Write(System.String,System.Boolean[])" />
		// Token: 0x060006F1 RID: 1777 RVA: 0x00024870 File Offset: 0x00022A70
		[DebuggerStepThrough]
		public override Task<OperateResult> WriteAsync(string address, bool[] values)
		{
			PanasonicMewtocolOverTcp.<WriteAsync>d__16 <WriteAsync>d__ = new PanasonicMewtocolOverTcp.<WriteAsync>d__16();
			<WriteAsync>d__.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
			<WriteAsync>d__.<>4__this = this;
			<WriteAsync>d__.address = address;
			<WriteAsync>d__.values = values;
			<WriteAsync>d__.<>1__state = -1;
			<WriteAsync>d__.<>t__builder.Start<PanasonicMewtocolOverTcp.<WriteAsync>d__16>(ref <WriteAsync>d__);
			return <WriteAsync>d__.<>t__builder.Task;
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Panasonic.PanasonicMewtocolOverTcp.Write(System.String,System.Boolean)" />
		// Token: 0x060006F2 RID: 1778 RVA: 0x000248C4 File Offset: 0x00022AC4
		[DebuggerStepThrough]
		public override Task<OperateResult> WriteAsync(string address, bool value)
		{
			PanasonicMewtocolOverTcp.<WriteAsync>d__17 <WriteAsync>d__ = new PanasonicMewtocolOverTcp.<WriteAsync>d__17();
			<WriteAsync>d__.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
			<WriteAsync>d__.<>4__this = this;
			<WriteAsync>d__.address = address;
			<WriteAsync>d__.value = value;
			<WriteAsync>d__.<>1__state = -1;
			<WriteAsync>d__.<>t__builder.Start<PanasonicMewtocolOverTcp.<WriteAsync>d__17>(ref <WriteAsync>d__);
			return <WriteAsync>d__.<>t__builder.Task;
		}

		/// <inheritdoc />
		// Token: 0x060006F3 RID: 1779 RVA: 0x00024916 File Offset: 0x00022B16
		public override string ToString()
		{
			return string.Format("PanasonicMewtocolOverTcp[{0}:{1}]", this.IpAddress, this.Port);
		}
	}
}
